from datetime import datetime
from typing import List, Tuple
from fastapi import HTTPException, UploadFile
from tortoise.contrib.pydantic import pydantic_model_creator
from model.sysUserPostModel import SysUserPost
from schema.sysUserPostSchema import SysUserPostCreate, SysUserPostUpdate, PageParams
from io import BytesIO
from excel.sysUserPostExcel import SysUserPostExcel


class PydanticConfig:
    alias_generator = lambda x: ''.join(word.capitalize() if i else word for i, word in enumerate(x.split('_')))
    allow_population_by_field_name = True


SysUserPost_Pydantic = pydantic_model_creator(SysUserPost, name="SysUserPost", config_class=PydanticConfig)


class SysUserPostService:
    @staticmethod
    async def create(data: SysUserPostCreate, creator: str) -> SysUserPost:
        """Create new record"""
        data_dict = data.dict(exclude_unset=True)
        data_dict["create_by"] = creator
        data_dict["create_time"] = datetime.now()
        data_dict["status"] = '0'

        obj = await SysUserPost.create(**data_dict)
        return await SysUserPost_Pydantic.from_tortoise_orm(obj)

    @staticmethod
    async def get_by_id(id: int) -> SysUserPost:
        """Get record by ID"""
        obj = await SysUserPost.get_or_none(id=id, status='0')
        if not obj:
            raise HTTPException(status_code=404, detail="用户与岗位关联表不存在")
        return await SysUserPost_Pydantic.from_tortoise_orm(obj)

    @staticmethod
    async def update(id: int, data: SysUserPostUpdate, updater: str) -> SysUserPost:
        """Update record"""
        obj = await SysUserPost.get_or_none(id=id, status='0')
        if not obj:
            raise HTTPException(status_code=404, detail="用户与岗位关联表不存在")

        update_dict = data.dict(exclude_unset=True)
        update_dict["update_by"] = updater
        update_dict["update_time"] = datetime.now()

        await obj.update_from_dict(update_dict).save()
        return await SysUserPost_Pydantic.from_tortoise_orm(obj)

    @staticmethod
    async def delete(ids: List[int], updater: str) -> int:
        """Batch delete records"""
        update_data = {
            "status": '2',
            "update_by": updater,
            "update_time": datetime.now()
        }
        count = await SysUserPost.filter(id__in=ids, status='0').update(**update_data)
        return count

    @staticmethod
    async def get_page(params: PageParams) -> Tuple[List[SysUserPost], int]:
        """Get page list"""
        query = SysUserPost.filter(status='0')

        # Build query conditions

        if params.create_by:
            query = query.filter(create_by__icontains=params.create_by)

        if params.update_by:
            query = query.filter(update_by__icontains=params.update_by)

        if params.status:
            query = query.filter(status__icontains=params.status)

        total = await query.count()

        records = await query.offset((params.page_num - 1) * params.page_size)             .limit(params.page_size)             .order_by("-create_time")

        return [await SysUserPost_Pydantic.from_tortoise_orm(record) for record in records], total

    @staticmethod
    async def export_excel() -> BytesIO:
        """Export all data to Excel"""
        records = await SysUserPost.filter(status='0').all()
        return await SysUserPostExcel.export_data(records)

    @staticmethod
    def get_import_template() -> BytesIO:
        """Get import template"""
        return SysUserPostExcel.get_import_template()

    @staticmethod
    async def import_data(file: UploadFile, creator: str) -> Tuple[int, List[str]]:
        """Import data"""
        content = await file.read()
        file_bytes = BytesIO(content)

        try:
            data_list = SysUserPostExcel.parse_import_data(file_bytes)
        except ValueError as e:
            raise HTTPException(status_code=400, detail=str(e))
        except Exception as e:
            raise HTTPException(status_code=400, detail="Excel文件格式错误")

        success_count = 0
        error_msgs = []

        for index, item_data in enumerate(data_list, start=1):
            try:
                item_data['create_by'] = creator
                item_data['create_time'] = datetime.now()
                item_data['status'] = '0'

                await SysUserPost.create(**item_data)
                success_count += 1

            except Exception as e:
                error_msgs.append(f"第{index}行: {str(e)}")

        return success_count, error_msgs